<html>
<head>
  <title>libicns documentation</title>
</head>
<body>
<FONT SIZE="+2"><B>libicns Documentation</B></FONT>
<BR>
<BR>
Copyright (C) 2012 Mathew Eis<BR>
Released under the terms of the LGPL v2 or later<BR>
libicns release 0.8.0, version 2:8:2
<BR>
<BR>
<a name="contents"></a>
<FONT SIZE="+1"><B>Table of contents:</B></FONT>
<P>
<ul>
<li><a href="#tutorial">Part I: Tutorial / Example</a>
  <ol type="i">
   <li>A quick read of a 128x128 icon with mask from 'test.icns'</li>
  </ol>
</li>
<br>
<li><a href="#datatypes">Part II: Data types and constants</a>
 <ol type="i">
   <li>Basic Data Types</li>
   <li>Icon Family and Element Header Types</li>
   <li>Icon Family and Element Types</li>
   <li>Icon Image Type</li>
   <li>Icon Info Type</li>
   <li>Icon Type Constants</li>
   <li>File/Resource Type Constants</li>
   <li>Error return codes</li>
 </ol>
</li>
<br>
<li><a href="#iconfamily">Part III: Manipulating the icon family</a>
 <ol type="i">
   <li>Reading and writing to files</li>
   <li>Reading specifically from an HFS+ resource fork (i.e. icon.icns/..namedfork/rsrc)</li>
   <li>Reading and writing to memory</li>
   <li>Creating an new icon family</li>
   <li>Counting the number of elements in an icon family</li>
 </ol>
</li>
<br>
<li><a href="#iconelement">Part IV: Manipulating elements of the icon family</a>
 <ol type="i">
   <li>Getting and setting elements of the icon family</li>
   <li>Adding and removing new elements of the icon family</li>
   <li>Creating new elements from image data</li>
   <li>Updating existing elements with image data</li>
 </ol>
</li>
<br>
<li><a href="#iconimage">Part V: Manipulating images of the icon family and icon elements</a>
 <ol type="i">
   <li>Fast retrival of a complete icon image from an icon family</li>
   <li>Retrieving a image or mask from an icon element</li>
   <li>Initializing an empty image - ready for data</li>
   <li>Freeing the memory allocated by an icon image</li>
 </ol>
</li>
<br>
<li><a href="#transcoding">Part VI: Decoding and encoding image data for certain formats</a>
 <ol type="i">
   <li>Decoding and encoding 3 channel RLE data</li>
   <li>Decoding and encoding jpeg2000 image data</li>
 </ol>
</li>
<br>
<li><a href="#misc">Part VII: Misc utility functions</a>
 <ol type="i">
   <li>Getting information about a specific icon type</li>
   <li>Finding the correct mask type with an icon type</li>
   <li>Determining the correct icon type to use for a given image</li>
   <li>Comparing icns_type_t data</li>
   <li>Enable or disable the printing of error messages during runtime</li>
 </ol>
</li>
</ul>
</P>
<HR>
<a name="tutorial"></a>
<FONT SIZE="+2"><B>Part I: Tutorial / Example</B></FONT>
<BR>
<BR>
<FONT SIZE="+1"><B>A quick read of a 128x128 icon with mask from 'test.icns'</B></FONT>
<PRE>
#include &lt;stdio.h&gt;

#include "icns.h"

int main(void)
{
	int		error = 0;
	FILE            *inFile = NULL;
	icns_family_t	*iconFamily = NULL;
	icns_image_t	iconImage;

	inFile = fopen( "test.icns", "r" );

	if( inFile == NULL ) {
		fprintf(stderr,"Unable to open test.icns!\n");
		goto cleanup;
	}

	// Import icon family from the file data
	error = icns_read_family_from_file(inFile,&iconFamily);

	fclose(inFile);

	if(error) {
		fprintf(stderr,"Unable to read icns family from file!\n");
	} else {

		// Read in a 128x128 32-bit RGBA image (with mask in alpha channel)
		// from the 128x128 32-bit icon and 128x128 8-bit mask
		error = icns_get_image32_with_mask_from_family(iconFamily,ICNS_128X128_32BIT_DATA,&iconImage);

		if(error) {
			fprintf(stderr,"Unable to get 128x128 image icon family!\n");
		} else {
			// Print out some information about the image
			printf("width: %d\n",image->imageWidth);
			printf("height: %d\n",image->imageHeight);
			printf("image channels: %d\n",image->imageChannels);
			printf("image pixel depth: %d\n",image->imagePixelDepth);
			printf("image data size: %ul\n",image->imageDataSize);
		}

		// Free the memory used by the image
		icns_image_free(&iconImage);
	}

	// Free the memory used by the icon family
	if(iconFamily != NULL) {
		free(iconFamily);
		iconFamily = NULL;
	}

	return error;
}
</PRE>
<HR>
<a name="datatypes"></a>
<FONT SIZE="+2"><B>Part II: Data types and constants</B></FONT>
<BR>
<BR>
<FONT SIZE="+1"><B>Basic Data Types</B></FONT>
<P>
To ensure that libicns can be easily ported to various systems, it
uses it's own data types, based off standard C library as defined
in &lt;stdint.h&gt;:
<BR><BR>
<table cellspacing=2>
<tr><th align=left>stdint.h type</th><th align=left>libicns type</th><th align=left>description</th></tr>
<tr><td>uint8_t</td><td>icns_bool_t</td><td>flag</td></tr>
<tr><td>uint8_t</td><td>icns_uint8_t</td><td>8-bit unsigned int</td></tr>
<tr><td>int8_t</td><td>icns_sint8_t</td><td>8-bit signed int</td></tr>
<tr><td>uint16_t</td><td>icns_uint16_t</td><td>16-bit unsigned int</td></tr>
<tr><td>int16_t</td><td>icns_sint16_t</td><td>16-bit signed int</td></tr>
<tr><td>uint32_t</td><td>icns_uint32_t</td><td>32-bit unsigned int</td></tr>
<tr><td>int32_t</td><td>icns_sint32_t</td><td>32-bit signed int</td></tr>
<tr><td>uint64_t</td><td>icns_uint64_t</td><td>64-bit unsigned int</td></tr>
<tr><td>int64_t</td><td>icns_sint64_t</td><td>64-bit signed int</td></tr>
<tr><td>uint8_t</td><td>icns_byte_t</td><td>8-bit unsigned int</td></tr>
</table>
<BR>
Please note that if porting to a different system, the bit-widths are important.
</P>

<FONT SIZE="+1"><B>Icon Family and Element Header Types</B></FONT>

<P>
The type and size of an icon family or element:
<PRE>
typedef struct icns_type_t {
  int8_t                c[4];
} icns_type_t;

typedef int32_t         icns_size_t;
</PRE>
</P>

<BR>
<FONT SIZE="+1"><B>Icon Family and Element Types</B></FONT>

<P>
The structure of an icon element:
<PRE>
typedef struct icns_element_t {
  icns_type_t           elementType;    /* 'ICN#', 'icl8', etc... */
  icns_size_t           elementSize;    /* Total size of element  */
  icns_byte_t           elementData[1]; /* icon image data */
} icns_element_t;
</PRE>
</P>

<P>
The structure of an icon family:
<PRE>
typedef struct icns_family_t {
  icns_type_t           resourceType;	/* Always should be 'icns' */
  icns_size_t           resourceSize;	/* Total size of resource  */
  icns_element_t        elements[1];    /* icon elements */
} icns_family_t;
</PRE>
</P>

<BR>
<FONT SIZE="+1"><B>Icon Image Type</B></FONT>

<P>
The structure of an icon image
<PRE>
typedef struct icns_image_t
{
  icns_uint32_t         imageWidth;     // width of image in pixels
  icns_uint32_t         imageHeight;    // height of image in pixels
  icns_uint8_t          imageChannels;  // number of channels in data
  icns_uint16_t         imagePixelDepth;// number of bits-per-pixel
  icns_uint64_t         imageDataSize;  // bytes = width * height * depth / bits-per-pixel
  icns_byte_t           *imageData;     // pointer to base address of uncompressed raw image data
} icns_image_t;
</PRE>
</P>

<BR>
<FONT SIZE="+1"><B>Icon Info Type</B></FONT>

<P>
Information about a given icon type
<PRE>
typedef struct icns_icon_info_t
{
  icns_type_t           iconType;         // type of icon (or mask)
  icns_bool_t           isImage;          // is this type an image
  icns_bool_t           isMask;           // is this type a mask
  icns_uint32_t         iconWidth;        // width of icon in pixels
  icns_uint32_t         iconHeight;       // height of icon in pixels
  icns_uint8_t          iconChannels;     // number of channels in data
  icns_uint16_t         iconPixelDepth;   // number of bits-per-pixel
  icns_uint16_t         iconBitDepth;     // overall bit depth = iconPixelDepth * iconChannels
  icns_uint64_t         iconRawDataSize;  // uncompressed bytes = width * height * depth / bits-per-pixel
} icns_icon_info_t;
</PRE>
</P>

<BR>
<FONT SIZE="+1"><B>Icon Type Constants</B></FONT>

<P>
The various icon types found within an icon family:
<PRE>
static const icns_type_t  ICNS_TABLE_OF_CONTENTS         = {{'T','O','C',' '}};
static const icns_type_t  ICNS_ICON_VERSION              = {{'i','c','n','V'}};
static const icns_type_t  ICNS_1024x1024_32BIT_ARGB_DATA = {{'i','c','1','0'}};
static const icns_type_t  ICNS_512x512_32BIT_ARGB_DATA   = {{'i','c','0','9'}};
static const icns_type_t  ICNS_256x256_32BIT_ARGB_DATA   = {{'i','c','0','8'}};
static const icns_type_t  ICNS_128X128_32BIT_DATA        = {{'i','t','3','2'}};
static const icns_type_t  ICNS_128X128_8BIT_MASK         = {{'t','8','m','k'}};
static const icns_type_t  ICNS_48x48_1BIT_DATA           = {{'i','c','h','#'}};
static const icns_type_t  ICNS_48x48_4BIT_DATA           = {{'i','c','h','4'}};
static const icns_type_t  ICNS_48x48_8BIT_DATA           = {{'i','c','h','8'}};
static const icns_type_t  ICNS_48x48_32BIT_DATA          = {{'i','h','3','2'}};
static const icns_type_t  ICNS_48x48_1BIT_MASK           = {{'i','c','h','#'}};
static const icns_type_t  ICNS_48x48_8BIT_MASK           = {{'h','8','m','k'}};
static const icns_type_t  ICNS_32x32_1BIT_DATA           = {{'I','C','N','#'}};
static const icns_type_t  ICNS_32x32_4BIT_DATA           = {{'i','c','l','4'}};
static const icns_type_t  ICNS_32x32_8BIT_DATA           = {{'i','c','l','8'}};
static const icns_type_t  ICNS_32x32_32BIT_DATA          = {{'i','l','3','2'}};
static const icns_type_t  ICNS_32x32_1BIT_MASK           = {{'I','C','N','#'}};
static const icns_type_t  ICNS_32x32_8BIT_MASK           = {{'l','8','m','k'}};
static const icns_type_t  ICNS_16x16_1BIT_DATA           = {{'i','c','s','#'}};
static const icns_type_t  ICNS_16x16_4BIT_DATA           = {{'i','c','s','4'}};
static const icns_type_t  ICNS_16x16_8BIT_DATA           = {{'i','c','s','8'}};
static const icns_type_t  ICNS_16x16_32BIT_DATA          = {{'i','s','3','2'}};
static const icns_type_t  ICNS_16x16_1BIT_MASK           = {{'i','c','s','#'}};
static const icns_type_t  ICNS_16x16_8BIT_MASK           = {{'s','8','m','k'}};
static const icns_type_t  ICNS_16x12_1BIT_DATA           = {{'i','c','m','#'}};
static const icns_type_t  ICNS_16x12_4BIT_DATA           = {{'i','c','m','4'}};
static const icns_type_t  ICNS_16x12_1BIT_MASK           = {{'i','c','m','#'}};
static const icns_type_t  ICNS_16x12_8BIT_DATA           = {{'i','c','m','8'}};
static const icns_type_t  ICNS_32x32_1BIT_ICON           = {{'I','C','O','N'}};
</PRE>
</P>

<P>
Used for initializing variables or during errors:
<PRE>
static const icns_type_t  ICNS_NULL_DATA                 = {{ 0 , 0 , 0 , 0 }};
static const icns_type_t  ICNS_NULL_MASK                 = {{ 0 , 0 , 0 , 0 }};
</PRE>
</P>

<BR>
<FONT SIZE="+1"><B>File/Resource Type Constants</B></FONT>

<P>
The icns family data type:
<PRE>
static const icns_type_t  ICNS_FAMILY_TYPE               = {{'i','c','n','s'}};
</PRE>
</P>

<P>
The Macbinary file header:
<PRE>
static const icns_type_t  ICNS_MACBINARY_TYPE            = {{'m','B','I','N'}};
</PRE>
</P>

<P>
Used for initializing variables or during errors:
<PRE>
static const icns_type_t  ICNS_NULL_TYPE                 = {{ 0 , 0 , 0 , 0 }};
</PRE>
</P>

</PRE>

<BR>
<FONT SIZE="+1"><B>Error return codes</B></FONT>

<P>
Constants returned by most libicns functions:
<BR>
<table cellspacing=2>
<tr><th align=left>return code constant</th><th align=left>value</th><th align=left>description</th></tr>
<tr><td>ICNS_STATUS_OK </td><td>0</td><td>no error</td></tr>
<tr><td>ICNS_STATUS_NULL_PARAM</td><td>-1</td><td>a null pointer was passed to a function</td></tr>
<tr><td>ICNS_STATUS_NO_MEMORY</td><td>-2</td><td>an error occurred allocating memory</td></tr>
<tr><td>ICNS_STATUS_INVALID_DATA</td><td>-3</td><td>invalid data was read or passed to a function</td></tr>
<tr><td>ICNS_STATUS_IO_READ_ERR</td><td>1</td><td>an error occurred while reading a file</td></tr>
<tr><td>ICNS_STATUS_IO_WRITE_ERR</td><td>2</td><td>an error occurred while writing to a file</td></tr>
<tr><td>ICNS_STATUS_DATA_NOT_FOUND</td><td>3</td><td>the necessary or requested data was not found</td></tr>
<tr><td>ICNS_STATUS_UNSUPPORTED</td><td>4</td><td>the requested data was not supported by libicns</td></tr>
</table>
</P>

<HR>
<a name="iconfamily"></a>
<FONT SIZE="+2"><B>Part III: Manipulating the icon family</B></FONT>
<BR>
<BR>
<FONT SIZE="+1"><B>Reading and writing to files</B></FONT>
<P>
int icns_write_family_to_file(FILE *dataFile,icns_family_t *iconFamilyIn);<BR>
int icns_read_family_from_file(FILE *dataFile,icns_family_t **iconFamilyOut);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Reading specifically from an HFS+ resource fork (i.e. icon.icns/..namedfork/rsrc)</B></FONT>
<P>
int icns_read_family_from_rsrc(FILE *rsrcFile,icns_family_t **iconFamilyOut);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Reading and writing to memory</B></FONT>
<P>
int icns_export_family_data(icns_family_t *iconFamily,icns_size_t *dataSizeOut,unsigned char **dataPtrOut);<BR>
int icns_import_family_data(icns_size_t dataSize,unsigned char *data,icns_family_t **iconFamilyOut);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Creating an new icon family</B></FONT>
<P>
int icns_create_family(icns_family_t **iconFamilyOut);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Counting the number of elements in an icon family</B></FONT>
<P>
int icns_count_elements_in_family(icns_family_t *iconFamily, icns_sint32_t *elementTotal)<BR>
</P>

<HR>
<a name="iconelement"></a>
<FONT SIZE="+2"><B>Part IV: Manipulating elements of the icon family</B></FONT>
<BR>
<BR>
<FONT SIZE="+1"><B>Getting and setting elements of the icon family</B></FONT>
<P>
int icns_get_element_from_family(icns_family_t *iconFamily,icns_type_t iconType,icns_element_t **iconElementOut);<BR>
int icns_set_element_in_family(icns_family_t **iconFamilyRef,icns_element_t *newIconElement);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Adding and removing new elements of the icon family</B></FONT>
<P>
int icns_add_element_in_family(icns_family_t **iconFamilyRef,icns_element_t *newIconElement);<BR>
int icns_remove_element_in_family(icns_family_t **iconFamilyRef,icns_type_t iconType);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Creating new elements from image data</B></FONT>
<P>
int icns_new_element_from_image(icns_image_t *imageIn,icns_type_t iconType,icns_element_t **iconElementOut);<BR>
int icns_new_element_from_mask(icns_image_t *imageIn,icns_type_t iconType,icns_element_t **iconElementOut);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Updating existing elements with image data</B></FONT>
<P>
int icns_update_element_with_image(icns_image_t *imageIn,icns_element_t **iconElement);<BR>
int icns_update_element_with_mask(icns_image_t *imageIn,icns_element_t **iconElement);<BR>
</P>

<HR>
<a name="iconimage"></a>
<FONT SIZE="+2"><B>Part V: Manipulating images of the icon family and icon elements</B></FONT>
<BR>
<BR>
<FONT SIZE="+1"><B>Fast retrival of a complete icon image from an icon family</B></FONT>
<P>
int icns_get_image32_with_mask_from_family(icns_family_t *iconFamily,icns_type_t sourceType,icns_image_t *imageOut);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Retrieving a image or mask from an icon element</B></FONT>
<P>
int icns_get_image_from_element(icns_element_t *iconElement,icns_image_t *imageOut);<BR>
int icns_get_mask_from_element(icns_element_t *iconElement,icns_image_t *imageOut);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Initializing an empty image - ready for data</B></FONT>
<P>
int icns_init_image_for_type(icns_type_t iconType,icns_image_t *imageOut);<BR>
int icns_init_image(unsigned int iconWidth,unsigned int iconHeight,unsigned int iconChannels,unsigned int iconPixelDepth,icns_image_t *imageOut);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Freeing the memory allocated by an icon image</B></FONT>
<P>
int icns_free_image(icns_image_t *imageIn);<BR>
</P>

<HR>
<a name="transcoding"></a>
<FONT SIZE="+2"><B>Part VI: Decoding and encoding image data for certain formats</B></FONT>
<BR><BR>
<FONT SIZE="+1"><B>Decoding and encoding 3 channel RLE data</B></FONT>
<P>
int icns_decode_rle24_data(icns_size_t dataSizeIn, icns_byte_t *dataPtrIn,icns_size_t *dataSizeOut, icns_byte_t **dataPtrOut);<BR>
int icns_encode_rle24_data(icns_size_t dataSizeIn, icns_byte_t *dataPtrIn,icns_size_t *dataSizeOut, icns_byte_t **dataPtrOut);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Decoding and encoding jpeg2000 image data</B></FONT>
<P>
int icns_jp2_to_image(icns_size_t dataSize, icns_byte_t *dataPtr, icns_image_t **imageOut);<BR>
int icns_image_to_jp2(icns_image_t *image, icns_size_t *dataSizeOut, icns_byte_t **dataPtrOut);<BR>
</P>

<HR>
<a name="misc"></a>
<FONT SIZE="+2"><B>Part VII: Misc utility functions</B></FONT>
<BR>

<BR>
<FONT SIZE="+1"><B>Getting information about a specific icon type</B></FONT>
<P>
icns_icon_info_t icns_get_image_info_for_type(icns_type_t iconType);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Finding the correct mask type with an icon type</B></FONT>
<P>
icns_type_t icns_get_mask_type_for_icon_type(icns_type_t);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Determining the correct icon type to use for a given image</B></FONT>
<P>
icns_type_t icns_get_type_from_image_info(icns_icon_info_t iconInfo);<BR>
icns_type_t icns_get_type_from_image(icns_image_t iconImage);<BR>
icns_type_t icns_get_type_from_mask(icns_image_t iconImage);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Comparing icns_type_t data</B></FONT>
<P>
icns_bool_t icns_types_equal(icns_type_t typeA,icns_type_t typeB);<BR>
icns_bool_t icns_types_not_equal(icns_type_t typeA,icns_type_t typeB);<BR>
</P>

<BR>
<FONT SIZE="+1"><B>Enable or disable the printing of error messages during runtime</B></FONT>
<P>
void icns_set_print_errors(icns_bool_t shouldPrint);<BR>
</P>

</body>
</html>
